# auth.py
from flask import Flask, request, jsonify, session,redirect,url_for, current_app
from werkzeug.security import generate_password_hash, check_password_hash
from models import *
from itsdangerous import URLSafeTimedSerializer
import configparser,os
from functools import wraps
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import random
import string
import json
import uuid
from datetime import datetime, timedelta


# 序列化器用于生成安全的 session 令牌
config_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'config.cfg')
config = configparser.ConfigParser()
config.read(config_path)
serializer = URLSafeTimedSerializer(config['APP']['SECRET_KEY'])
#session入库未实现
#================================
def create_session(user_id):
    session_data = {
        # 存储用户ID或其他会话信息
        'user_id': user_id,
        # 其他会话数据...
    }
    expiration = datetime.utcnow() + timedelta(days=1)  # 设置会话过期时间
    session = Session(session_data=json.dumps(session_data), expiration=expiration)
    db.session.add(session)
    db.session.commit()
    return session.id

def get_session(session_id):
    session = Session.query.get(session_id)
    if session and session.expiration > datetime.utcnow():
        return json.loads(session.session_data)
    return None

def delete_session(session_id):
    session = Session.query.get(session_id)
    if session:
        db.session.delete(session)
        db.session.commit()
#==============================
def get_session_from_token(token):
    try:
        # 反序列化 Token，获取 session_id
        session_id_data = serializer.loads(token, max_age=3600)  # max_age 根据需求设置
        session_id = session_id_data.get('session_id')
        # 使用 session_id 查询数据库中的会话记录
        db_session = Session.query.get(session_id)
        return db_session
    except:
        # 处理 Token 无效或已过期的情况
        return None
        
def user_login():
    username = request.form['username']
    password = request.form['password']
    captcha_input = request.form['captcha'].upper()
    user = User.query.filter_by(username=username).first()
    
    if user and user.check_password(password) and session['captcha'] == captcha_input:
        # 登录成功，记录日志
        current_app.logger.info(f'User {username} logged in successfully from IP: {request.remote_addr}')
        
        # 设置会话数据
        session['user_id'] = user.id
        session['username'] = user.username
        session['logged_in'] = True
        
        response = jsonify({'success': True, 'message': u'登录成功'})
        current_app.logger.info(f'Login response for {username}: {response.get_json()}')
        return response
    
    # 登录失败，记录日志
    current_app.logger.warning(f'Failed login attempt for user: {username} from IP: {request.remote_addr}')
    return jsonify({'success': False, 'message': u'用户名、密码或验证码错误'})

def user_logout():
    username = session.get('username', 'unknown')
    current_app.logger.info(f'User {username} logging out from IP: {request.remote_addr}')
    session.clear()
    current_app.logger.info(f'User {username} logged out successfully')
    return jsonify({'message': 'Logout successful'})

# 检查用户是否登录
def is_logged_in():
    return session.get('logged_in', False)

def login_required(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if not is_logged_in():
            return redirect(url_for('login'))
        return f(*args, **kwargs)
    return decorated_function

def generate_captcha():
    char_set = string.ascii_uppercase + string.digits
    captcha_text = ''.join(random.choice(char_set) for _ in range(6))
    session['captcha'] = captcha_text
    
    # 使用相对于 static 目录的路径
    font_path = os.path.join('static', 'font', 'vtksgiz.ttf')
    # 获取绝对路径
    abs_font_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), font_path)
    
    if not os.path.exists(abs_font_path):
        # 如果找不到字体文件，记录错误并使用系统字体
        print(f"Font file not found at: {abs_font_path}")
        font_path = "C:\\Windows\\Fonts\\arial.ttf"
    else:
        font_path = abs_font_path
    
    font_size = 20
    font = ImageFont.truetype(font_path, font_size)
    
    # 创建一个空白图像用于测量文本大小
    test_image = Image.new('RGB', (1, 1))
    test_draw = ImageDraw.Draw(test_image)
    
    # 计算文本尺寸
    text_width, text_height = test_draw.textsize(captcha_text, font)
    
    # 创建图像，确保宽度足够容纳文本
    img_width = text_width + 8
    img_height = text_height + 12
    img = Image.new('RGB', (img_width, img_height), (255, 255, 255))
    d = ImageDraw.Draw(img)

    # 随机颜色
    color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
    
    # 绘制文本
    x = (img.width - text_width) // 2
    y = (img.height - text_height) // 2
    d.text((x, y), captcha_text, fill=color, font=font)
    
    return img